package net.simflow.swf.analyzer.gui.exec.para;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map.Entry;
import java.util.TreeMap;

import net.simflow.swf.analyzer.exec.data.ExecParameterPkg;
import net.simflow.swf.analyzer.gui.ConfigDialog;
import net.simflow.swf.analyzer.network.data.Flow;
import net.simflow.swf.analyzer.network.data.Service;

import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Shell;

public class ExecParameterSettingDialog extends ConfigDialog {
	HashMap<String, Composite> binding;
	LinkedHashMap<String, ArrayList<String>> tree;

	private static final String SERVICE_ABILITY = "Service Ability";
	private static final String SERVICE_SCHEDULE = "Service Schedule";
	private static final String FLOW_WEIGHT = "Flow Weight";
	private static final String FLOW_RELDEADLINE = "Flow Relative Deadline";
	private static final String EXECUTION = "Execution";

	private ExecParameterPkg execConditionPkg;

	private TreeMap<String, Service> svcAbilityNameMap;
	private TreeMap<String, Integer> svcAbilityMap;
	private TreeMap<String, Service> svcScheduleNameMap;
	private TreeMap<String, Integer> svcScheduleMap;
	private TreeMap<String, Flow> flowWeightNameMap;
	private TreeMap<String, Integer> flowWeightMap;
	private TreeMap<String, Flow> flowRelDeadlineNameMap;
	private TreeMap<String, Integer> flowRelDeadlineMap;

	private ExecMapSettingComposite cmpServiceAbility;
	private ExecMapSettingComposite cmpServiceSchedule;
	private ExecMapSettingComposite cmpFlowWeight;
	private ExecMapSettingComposite cmpFlowRelDeadline;
	private ExecGeneralComposite cmpExecution;

	/**
	 * Create the shell.
	 * 
	 * @param display
	 */
	public ExecParameterSettingDialog(Shell parent, String title,
			ExecParameterPkg execConditionPkg) {
		super(parent, "Exection Condition Setting: " + title, new Point(900,
				600));
		this.execConditionPkg = execConditionPkg;

		if (this.execConditionPkg == null) {
			return;
		}

		svcAbilityNameMap = new TreeMap<String, Service>();
		svcAbilityMap = new TreeMap<String, Integer>();
		for (Entry<Service, Integer> en : this.execConditionPkg
				.getServiceAbilityMap().entrySet()) {
			svcAbilityNameMap.put(en.getKey().getFullInfo(), en.getKey());
			svcAbilityMap.put(en.getKey().getFullInfo(), en.getValue());
		}
		svcAbilityNameMap.comparator();
		svcAbilityMap.comparator();

		TreeMap<String, Integer> defaultSvcAbilityMap = new TreeMap<String, Integer>();
		for (Entry<Service, Integer> en : this.execConditionPkg
				.getDefaultServiceAbilityMap().entrySet()) {
			defaultSvcAbilityMap.put(en.getKey().getFullInfo(), en.getValue());
		}
		defaultSvcAbilityMap.comparator();

		svcScheduleNameMap = new TreeMap<String, Service>();
		svcScheduleMap = new TreeMap<String, Integer>();
		for (Entry<Service, Integer> en : this.execConditionPkg
				.getServiceScheduleMap().entrySet()) {
			svcScheduleNameMap.put(en.getKey().getFullInfo(), en.getKey());
			svcScheduleMap.put(en.getKey().getFullInfo(), en.getValue());
		}
		svcScheduleNameMap.comparator();
		svcScheduleMap.comparator();

		TreeMap<String, Integer> defaultSvcScheduleMap = new TreeMap<String, Integer>();
		for (Entry<Service, Integer> en : this.execConditionPkg
				.getDefaultServiceScheduleMap().entrySet()) {
			defaultSvcScheduleMap.put(en.getKey().getFullInfo(), en.getValue());
		}
		defaultSvcScheduleMap.comparator();

		flowWeightNameMap = new TreeMap<String, Flow>();
		flowWeightMap = new TreeMap<String, Integer>();
		for (Entry<Flow, Integer> en : this.execConditionPkg.getFlowWeightMap()
				.entrySet()) {
			flowWeightNameMap.put(en.getKey().getNameInNetwork(), en.getKey());
			flowWeightMap.put(en.getKey().getNameInNetwork(), en.getValue());
		}
		flowWeightNameMap.comparator();
		flowWeightMap.comparator();

		TreeMap<String, Integer> defaultFlowWeightMap = new TreeMap<String, Integer>();
		for (Entry<Flow, Integer> en : this.execConditionPkg
				.getDefaultFlowWeightMap().entrySet()) {
			defaultFlowWeightMap.put(en.getKey().getNameInNetwork(),
					en.getValue());
		}
		defaultFlowWeightMap.comparator();

		flowRelDeadlineNameMap = new TreeMap<String, Flow>();
		flowRelDeadlineMap = new TreeMap<String, Integer>();
		for (Entry<Flow, Integer> en : this.execConditionPkg
				.getFlowRelDeadlineMap().entrySet()) {
			flowRelDeadlineNameMap.put(en.getKey().getNameInNetwork(),
					en.getKey());
			flowRelDeadlineMap.put(en.getKey().getNameInNetwork(),
					en.getValue());
		}
		flowRelDeadlineNameMap.comparator();
		flowRelDeadlineMap.comparator();

		TreeMap<String, Integer> defaultFlowRelDeadlineMap = new TreeMap<String, Integer>();
		for (Entry<Flow, Integer> en : this.execConditionPkg
				.getDefaultFlowRelDeadlineMap().entrySet()) {
			defaultFlowRelDeadlineMap.put(en.getKey().getNameInNetwork(),
					en.getValue());
		}
		defaultFlowRelDeadlineMap.comparator();

		cmpServiceSchedule = new ExecMapSettingComposite(parent, "Service",
				"Schedule", svcScheduleMap, defaultSvcScheduleMap);
		cmpServiceAbility = new ExecMapSettingComposite(parent, "Service",
				"Ability", svcAbilityMap, defaultSvcAbilityMap);
		cmpFlowRelDeadline = new ExecMapSettingComposite(parent, "Flow",
				"RelDeadline", flowRelDeadlineMap, defaultFlowRelDeadlineMap);
		cmpFlowWeight = new ExecMapSettingComposite(parent, "Flow", "Weight",
				flowWeightMap, defaultFlowWeightMap);
		cmpExecution = new ExecGeneralComposite(parent, execConditionPkg);

		binding = new HashMap<String, Composite>();
		binding.put(SERVICE_ABILITY, cmpServiceAbility);
		binding.put(SERVICE_SCHEDULE, cmpServiceSchedule);
		binding.put(FLOW_WEIGHT, cmpFlowWeight);
		binding.put(FLOW_RELDEADLINE, cmpFlowRelDeadline);
		binding.put(EXECUTION, cmpExecution);

		tree = new LinkedHashMap<String, ArrayList<String>>();
		tree.put(SERVICE_SCHEDULE, null);
		tree.put(SERVICE_ABILITY, null);
		tree.put(FLOW_RELDEADLINE, null);
		tree.put(FLOW_WEIGHT, null);
		tree.put(EXECUTION, null);
	}

	@Override
	protected HashMap<String, Composite> getBinding() {
		return binding;
	}

	@Override
	protected LinkedHashMap<String, ArrayList<String>> getTree() {
		return tree;
	}

	@Override
	protected void save() {
		if (this.execConditionPkg == null) {
			return;
		}

		this.cmpExecution.save();

		TreeMap<String, Integer> map;

		map = cmpServiceAbility.getResult();
		for (Entry<String, Integer> en : map.entrySet()) {
			this.execConditionPkg.getServiceAbilityMap().put(
					svcAbilityNameMap.get(en.getKey()), en.getValue());
		}

		map = cmpServiceSchedule.getResult();
		for (Entry<String, Integer> en : map.entrySet()) {
			this.execConditionPkg.getServiceScheduleMap().put(
					svcScheduleNameMap.get(en.getKey()), en.getValue());
		}

		map = cmpFlowRelDeadline.getResult();
		for (Entry<String, Integer> en : map.entrySet()) {
			this.execConditionPkg.getFlowRelDeadlineMap().put(
					flowRelDeadlineNameMap.get(en.getKey()), en.getValue());
		}

		map = cmpFlowWeight.getResult();
		for (Entry<String, Integer> en : map.entrySet()) {
			this.execConditionPkg.getFlowWeightMap().put(
					flowWeightNameMap.get(en.getKey()), en.getValue());
		}
	}
}
